package com.guoxue.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
 * Jedis连接池，请确保使用jedis后释放资源
 * @author young
 *
 */
public class RedisUtil {
    
    //Redis服务器IP
    private static String ADDR = "192.168.0.116";
    //Redis的端口号
    private static int PORT = 6379;
    
    //如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
    private static int MAX_ACTIVE = -1;
    
    //控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8。
    private static int MAX_IDLE = 200;
    
    //等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
    private static int MAX_WAIT = 10000;
    
    private static int TIMEOUT = 10000;
    
    //在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
    private static boolean TEST_ON_BORROW = true;
    
    private static JedisPool jedisPool = null;
    /**
     * 初始化Redis连接池
     */
    static {
        try {
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(MAX_ACTIVE);
            config.setMaxIdle(MAX_IDLE);
            config.setMaxWaitMillis(MAX_WAIT);
            config.setTestOnBorrow(TEST_ON_BORROW);
            jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取Jedis实例
     * @return
    */
    public synchronized static Jedis getJedis() {
        try {
            if (jedisPool != null) {
                Jedis resource = jedisPool.getResource();
                return resource;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
   }
    /**
     * 释放jedis资源
     * @param jedis
     */
    public static void close(final Jedis jedis) {
        if (jedis != null) {
        	jedis.close();
        }
    }
    /**
     * 序列化工具
     * @param <T>
     * @param obj
     * @return
     */
    public static byte[] serialize(Object obj){
    	ObjectOutputStream oos = null;
    	ByteArrayOutputStream baos = null;
    	try{
    		baos = new ByteArrayOutputStream();
    		oos = new ObjectOutputStream(baos);
    		oos.writeObject(obj);
    		byte[] bytes = baos.toByteArray();
    		return bytes;
    	} catch (Exception e) {
    		LoggerUtil.error(e);
    	} finally {
			try {
				oos.close();
				baos.close();
			} catch (IOException e) {
				LoggerUtil.error(e);
			}
		}
		return null;
    }
    /**
     * 反序列化
     * @param bytes
     * @return
     */
    public static Object unserialize(byte[] bytes){
    	ByteArrayInputStream bais = null;
    	ObjectInputStream oi = null;
    	Object obj = null;
    	if (bytes==null){
    		return null;
    	}
    	try{
    		bais = new ByteArrayInputStream(bytes);
    		oi = new ObjectInputStream(bais);
    		obj =  oi.readObject();
    	}catch (Exception e) {
    		LoggerUtil.error(e);
		}finally {
			try {
				bais.close();
				oi.close();
			} catch (IOException e) {
				LoggerUtil.error(e);
			}
		}
		return obj;
    }
}
